package com.example.validdemo.controller;


import cn.hutool.core.util.ObjectUtil;
import com.example.validdemo.model.*;
import com.example.validdemo.service.SysUserServiceImpl;
import com.example.validdemo.util.PatternUtil;
import com.example.validdemo.util.ValidateUtil;
import com.example.validdemo.validator.DateValidator;
import com.example.validdemo.validator.Validator;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.google.common.collect.ImmutableBiMap;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import java.util.List;
import java.util.Map;

/**
 * 系统用户(SysUser)表控制层
 *
 * @author hbx
 * @since 2021-09-26 17:46:46
 */
@Slf4j
@RestController
@RequestMapping("sysUser")
@Api(tags = "用户控制器")
@RequiredArgsConstructor
@Validated
public class SysUserController extends ApiController {

    @Resource
    private SysUserServiceImpl sysUserService;

    /**
     * 添加用户
     *
     * @param sysUser sysUser
     * @return R
     * @author Bx_Hu
     * @date 19:31 2021-9-26
     **/
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "添加用户-校验参数1")
    @PostMapping("save1")
    public R<SysUser> save1(@RequestBody @ApiParam("用户") SysUser sysUser) {
        log.warn("sysUser = {}", sysUser);
        if (!PatternUtil.username(sysUser.getUsername())) {
            return failed("用户名格式错误");
        }
        if (!PatternUtil.mobile(sysUser.getMobile())) {
            return failed("手机号格式错误");
        }
        if (!PatternUtil.email(sysUser.getEmail())) {
            return failed("邮箱格式错误");
        }
        if (ObjectUtil.isEmpty(sysUser.getSex())) {
            return failed("性别必选");
        }
        return success(sysUser);
    }


    /**
     * 添加用户
     *
     * @param sysUsers sysUsers
     * @return R
     * @author Bx_Hu
     * @date 19:31 2021-9-26
     **/
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "添加用户-Bean Validation校验参数")
    @PostMapping("save2")
    public R<SysUser> save2(@RequestBody @ApiParam("用户") SysUser sysUsers) {
        List<String> validateMessages = ValidateUtil.validateMessages(sysUsers);
        if (ObjectUtil.isNotEmpty(validateMessages)) {
            log.warn("validateMessages = {}", validateMessages);
            return failed(validateMessages.get(0));
        }
        log.warn("sysUsers = {}", sysUsers);
        return success(sysUsers);
    }

    /**
     * 添加用户-Validated方式校验
     *
     * @param sysUser sysUser
     * @return R
     * @author Bx_Hu
     * @date 19:31 2021-9-26
     **/
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "添加用户-Validated方式Bean校验")
    @PostMapping("save3")
    public R<SysUser> save3(@RequestBody @Validated @ApiParam("用户") SysUser sysUser) {
        log.warn("sysUser = {}", sysUser);
        return success(sysUser);
    }


    /**
     * 添加用户-Valid方式校验
     * valid 不需要在类上加 @Validated 注解
     * validated 可以选择校验组
     *
     * @param sysUser sysUser
     * @return R
     * @author Bx_Hu
     * @date 19:31 2021-9-26
     **/
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "添加用户-Valid方式Bean校验")
    @PostMapping("save5")
    public R<SysUser> save5(@RequestBody @Valid @ApiParam("用户") SysUser sysUser) {
        log.warn("sysUser = {}", sysUser);
        return success(sysUser);
    }

    /**
     * Service添加用户-Validated方式Bean校验
     *
     * @param sysUser sysUser
     * @return R
     * @author Bx_Hu
     * @date 19:31 2021-9-26
     **/
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "Service添加用户-Validated方式Bean校验")
    @PostMapping("saveService")
    public R<SysUser> saveService(@RequestBody SysUser sysUser) {
        return success(sysUserService.saveUser(sysUser, null));
    }

    /**
     * 分组校验-添加用户
     *
     * @param sysUser sysUser
     * @return R
     * @author Bx_Hu
     * @date 19:31 2021-9-26
     **/
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "Bean分组校验-添加用户")
    @PostMapping("save4")
    public R<SysUserVO> save4(@RequestBody @Validated(Validator.Add.class) @ApiParam("用户") SysUserVO sysUser) {
        log.warn("sysUser = {}", sysUser);
        return success(sysUser);
    }


    /**
     * 分组校验-修改用户
     *
     * @param sysUser sysUser
     * @return R
     * @author Bx_Hu
     **/
    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "Bean分组校验-修改用户")
    @PostMapping("update1")
    public R<SysUserVO> update1(@RequestBody @Validated(Validator.Update.class) @ApiParam("用户") SysUserVO sysUser) {
        log.warn("sysUser = {}", sysUser);
        return success(sysUser);
    }


    /**
     * 入参校验-修改用户名,手机号,邮箱
     *
     * @param username 用户名
     * @param email    邮箱
     * @param mobile   手机号
     * @return com.example.validdemo.model.R<java.lang.String>
     * @author Bx_Hu
     * @date 13:00 2021-9-25
     **/
    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "入参校验-修改用户名,手机号,邮箱")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名", paramType = "query"),
            @ApiImplicitParam(name = "email", value = "邮箱"),
            @ApiImplicitParam(name = "mobile", value = "手机号"),
    })
    @PostMapping("update2")
    public R<Map<String, String>> update2(
            @RequestParam(required = false) @NotBlank(message = "用户名必填") @Size(message = "用户名字数不可大于20", max = 20) String username,
            @RequestParam(required = false) @NotBlank(message = "邮箱必填") @Pattern(regexp = PatternUtil.REG_EMAIL, message = "邮箱格式不正确") String email,
            @RequestParam(required = false) @NotBlank(message = "手机号必填") @Pattern(regexp = PatternUtil.REG_MOBILE, message = "手机号格式不正确") String mobile) {
        log.warn("username = {} email = {} mobile = {}", username, email, mobile);
        return success(ImmutableBiMap.of("username", username, "email", email, "mobile", mobile));
    }


    /**
     * 级联校验-添加用户角色
     *
     * @param userRoleVO userRoleVO
     * @return R
     * @author Bx_Hu
     **/
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "级联校验-添加用户角色")
    @PostMapping("saveUserRole")
    public R<UserRoleVO> saveUserRole(
            @RequestBody @Validated(Validator.Add.class) @ApiParam("用户") UserRoleVO userRoleVO) {
        log.warn("sysUser = {}", userRoleVO);
        return success(userRoleVO);
    }


    /**
     * 级联校验-添加角色权限
     *
     * @param rolePerVO rolePerVO
     * @return R
     * @author Bx_Hu
     **/
    @ApiOperationSupport(order = 8)
    @ApiOperation(value = "级联校验-添加角色权限")
    @PostMapping("saveRolePer")
    public R<RolePerVO> saveRolePer(
            @RequestBody @Validated(Validator.Add.class) @ApiParam("用户") RolePerVO rolePerVO) {
        log.warn("sysUser = {}", rolePerVO);
        return success(rolePerVO);
    }

    /**
     * 自定义校验注解-时间格式校验
     *
     * @return R
     * @author Bx_Hu
     **/
    @ApiOperationSupport(order = 9)
    @ApiOperation(value = "自定义校验注解-时间格式校验")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "dateTime", value = "yyyy-MM-dd HH:mm:ss", paramType = "query"),
            @ApiImplicitParam(name = "date", value = "yyyy-MM-dd", paramType = "query"),
    })
    @PostMapping("saveDefinition")
    public R<Map<String, String>> saveDefinition(
            @RequestParam(required = false) @DateValidator(message = "dateTime格式不匹配") String dateTime,
            @RequestParam(required = false) @DateValidator(message = "date格式不匹配", dateFormat = "yyyy-MM-dd") String date) {
        log.warn("dateTime = {} date = {}", dateTime, date);
        return success(ImmutableBiMap.of("dateTime", dateTime, "date", date));
    }


    /**
     * 自定义校验注解-时间格式校验
     * 修改年龄,且判断根据年龄是否需要禁用
     * 根据年龄大小,校验是否禁用
     *
     * @return R
     * @author Bx_Hu
     **/
    @ApiOperationSupport(order = 10)
    @ApiOperation(value = "逻辑校验-修改年龄,且判断根据年龄是否需要禁用")
    @PostMapping("logic")
    public R<SysUserAgeVO> logic(
            @RequestBody @Valid @ApiParam("用户") SysUserAgeVO sysUserAgeVO) {
        log.warn("sysUserAgeVO = {}", sysUserAgeVO);
        return success(sysUserAgeVO);
    }


}
